package com.zm.util;

import ch.ethz.ssh2.Connection;
import com.zm.core.ConnectionPools;
import com.zm.core.Ssh2ConnectionPools;
import com.zm.core.config.GetParamsByProperties;

import java.io.IOException;

/**
 * Created by ZM on 2022/2/18 10:12
 */
public class Ssh2Pool implements ConnectionPools {//懒汉式单例

     private static String ip= GetParamsByProperties.readProperties("remote.ip");
     private static String name=GetParamsByProperties.readProperties("remote.name");
     private static String password=GetParamsByProperties.readProperties("remote.password");

     private static boolean Ssh2PoolKey=false;//设置私有变量，除非获取这个名称，否则反射无法破坏单例
     private static Ssh2ConnectionPools connPools=null;
        //设置成单例模式，防止多次实例化连接池
        private Ssh2Pool(){//单例的关键是构造器私有
            synchronized (Ssh2Pool.class){
                if (Ssh2PoolKey==false){
                    Ssh2PoolKey=true;
                }else {
                    throw new RuntimeException("无需使用反射破坏单例");
                }
            }
        }
        private volatile static Ssh2Pool ssh2Pool;
        public static Ssh2Pool getInstance(){//单机下没事，多线程下会出错。所有这里要加双重检测锁模式才行，简称DCL懒汉式
            if (ssh2Pool==null){
                synchronized (Ssh2Pool.class){
                    if (ssh2Pool==null){
//new不是一个原子性操作，有三个步骤:1、分配内存空间；2、执行构造方法，初始化对象；3、把这个对象指向这个空间
//在多线程下，每个线程这3步的执行顺序可能不一样，就有可能造成出错，所以要禁止指令重排就得在定义lazyMan时加volatile!
                        ssh2Pool=new Ssh2Pool();
                    }
                }
            }
            return ssh2Pool;
        }
        static {
        connPools=new Ssh2ConnectionPools(ip,name,password);
        }

        @Override
        public int getInitConnections() {
            return connPools.getInitPoolSize();
        }

        @Override
        public void setInitConnections(int initConnections) {
            connPools.setInitPoolSize(initConnections);
        }

        @Override
        public int getIncrements() {
            return connPools.getIncrementSize();
        }

        @Override
        public void setIncrements(int increments) {
            connPools.setIncrementSize(increments);
        }

        @Override
        public int getMaxConnections() {
            return connPools.getMaxConnections();
        }

        @Override
        public void setMaxConnections(int maxConnections) {
            connPools.setMaxConnections(maxConnections);
        }

        @Override
        public void initPool() {
            connPools.createPool();
        }

        @Override
        public Connection getConnection() {
            Connection connection=null;
            try {
                connection= connPools.getConnection();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return connection;
        }

        @Override
        public void releaseConnection(Connection conn) {
            connPools.releaseConnection(conn);
        }

        @Override
        public void refreshPool() {
            try {
                connPools.refreshPool();
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void closePool() {
            try {
                connPools.closePools();
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
        }

    @Override
    public void narrowPools() {//缩小连接池
        connPools.narrowPools();
    }


}
